From: Brian Woods Date: Mon, 5 Feb 2018 09:15:25 +0000 (+0100) Subject: x86/svm: correct EFER.SVME intercept checks X-Git-Tag: archive/raspbian/4.11.1-1+rpi1~1^2~66^2~630 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22?a=commitdiff_plain;h=4619bff28cc709d0fea32494bda1786e63338295;p=xen.git x86/svm: correct EFER.SVME intercept checks Corrects some EFER.SVME checks in intercepts. See AMD APM vol2 section 15.4 for more details. VMMCALL isn't checked due to guests needing it to boot. Reported-by: Andrew Cooper Signed-off-by: Brian Woods Reviewed-by: Boris Ostrovsky --- diff --git a/xen/arch/x86/hvm/svm/nestedsvm.c b/xen/arch/x86/hvm/svm/nestedsvm.c index 1f7b0d3e88..1f5981fc18 100644 --- a/xen/arch/x86/hvm/svm/nestedsvm.c +++ b/xen/arch/x86/hvm/svm/nestedsvm.c @@ -1620,7 +1620,12 @@ void svm_vmexit_do_stgi(struct cpu_user_regs *regs, struct vcpu *v) { unsigned int inst_len; - if ( !nestedhvm_enabled(v->domain) ) { + /* + * STGI doesn't require SVME to be set to be used. See AMD APM vol + * 2 section 15.4 for details. + */ + if ( !nestedhvm_enabled(v->domain) ) + { hvm_inject_hw_exception(TRAP_invalid_op, X86_EVENT_NO_EC); return; } @@ -1640,7 +1645,8 @@ void svm_vmexit_do_clgi(struct cpu_user_regs *regs, struct vcpu *v) uint32_t general1_intercepts = vmcb_get_general1_intercepts(vmcb); vintr_t intr; - if ( !nestedhvm_enabled(v->domain) ) { + if ( !nsvm_efer_svm_enabled(v) ) + { hvm_inject_hw_exception(TRAP_invalid_op, X86_EVENT_NO_EC); return; } diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index dcbd550883..81cf5b8691 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -2193,7 +2193,6 @@ svm_vmexit_do_vmrun(struct cpu_user_regs *regs, { if ( !nsvm_efer_svm_enabled(v) ) { - gdprintk(XENLOG_ERR, "VMRUN: nestedhvm disabled, injecting #UD\n"); hvm_inject_hw_exception(TRAP_invalid_op, X86_EVENT_NO_EC); return; } @@ -2248,7 +2247,6 @@ svm_vmexit_do_vmload(struct vmcb_struct *vmcb, if ( !nsvm_efer_svm_enabled(v) ) { - gdprintk(XENLOG_ERR, "VMLOAD: nestedhvm disabled, injecting #UD\n"); hvm_inject_hw_exception(TRAP_invalid_op, X86_EVENT_NO_EC); return; } @@ -2284,7 +2282,6 @@ svm_vmexit_do_vmsave(struct vmcb_struct *vmcb, if ( !nsvm_efer_svm_enabled(v) ) { - gdprintk(XENLOG_ERR, "VMSAVE: nestedhvm disabled, injecting #UD\n"); hvm_inject_hw_exception(TRAP_invalid_op, X86_EVENT_NO_EC); return; } @@ -2758,6 +2755,11 @@ void svm_vmexit_handler(struct cpu_user_regs *regs) break; case VMEXIT_INVLPGA: + if ( !nsvm_efer_svm_enabled(v) ) + { + hvm_inject_hw_exception(TRAP_invalid_op, X86_EVENT_NO_EC); + break; + } if ( (inst_len = __get_instruction_length(v, INSTR_INVLPGA)) == 0 ) break; svm_invlpga_intercept(v, regs->rax, regs->ecx);